#region License, Terms and Conditions
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
#endregion
using System;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Pesta.Libraries.OAuth;
using Pesta.Libraries.OAuth.server;
using raya.Library.OAuth;
using raya.Models.oauth;

namespace raya.Controllers
{
    [HandleError]
    public class oauthController : baseController
    {
        public ActionResult Index()
        {
            // Add action logic here
            throw new NotImplementedException();
        }

        private readonly IOAuthDataStore oauthDataStore;

        public oauthController()
        {
#if AZURE
            oauthDataStore = RayaAzureOAuthDataStore.Instance;
#else
            oauthDataStore = RayaOAuthDataStore.Instance;
#endif
        }
        
        public void request_token()
        {
            try 
            {
                OAuthServer server = new OAuthServer(oauthDataStore);
                OAuthMessage requestMessage = OAuthServlet.getMessage(System.Web.HttpContext.Current.Request, null);
                OAuthRequest request = OAuthRequest.from_request();
                OAuthToken token = server.fetch_request_token(request, requestMessage);
                if (token != null)
                {
                    Response.Write(token.ToString());
                }
            } 
            catch (OAuthException e) 
            {
                Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                Response.StatusDescription = e.Message;
            } 
            catch (Exception e) 
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                Response.StatusDescription = e.Message;
            }
        }

        public void access_token()
        {
            try 
            {
                OAuthServer server = new OAuthServer(oauthDataStore);
                OAuthMessage requestMessage = OAuthServlet.getMessage(System.Web.HttpContext.Current.Request, null);
                OAuthRequest request = OAuthRequest.from_request();
                OAuthToken token = server.fetch_access_token(request, requestMessage);
                if (token != null) 
                {
                    Response.Write(token.ToString());
                }
            }
            catch (OAuthException e)
            {
                Response.StatusCode = 401;
                Response.StatusDescription = e.Message;
            }
            catch (Exception e) 
            {
                Response.StatusCode = 400;
                Response.StatusDescription = e.Message;
            }
        }

        public ActionResult authorize()
        {
            if (Session["id"] == null)
            {
                return Redirect("/login?redirect=" + HttpUtility.UrlEncode(Request.ServerVariables["REQUEST_URI"]));
            }
            OAuthRequest request = OAuthRequest.from_request();
            string token = request.get_parameter("oauth_token");
            string callback = request.get_parameter("oauth_callback");
            if (token == null) 
            {

                return RedirectToAction("error", new{ code = HttpStatusCode.BadRequest, descr = "Bad Request - missing oauth_token"});
            }
            oauth.OAuthInfo data = new oauth.OAuthInfo {oauth_callback = callback, oauth_token = token};
            return View("authorize", data);
        }

        public void approveAuthorization()
        {
            if (Session["id"] == null)
            {
                Redirect("/login?redirect=" + HttpUtility.UrlEncode(Request.ServerVariables["REQUEST_URI"]));
            }
            string oauthToken = Request.Params["oauth_token"];
            string oauthCallback = Request.Params["oauth_callback"];
            var ds = oauthDataStore;
            ds.authorize_request_token(oauthToken, Session["id"].ToString());
            // if callback was provided, append token and return to the callback
            if (!String.IsNullOrEmpty(oauthCallback))
            {
                oauthCallback += oauthCallback.IndexOf('?') == -1 ? "?" : "&";
                oauthCallback += "oauth_token=" + HttpUtility.UrlEncode(oauthToken);
                Redirect(oauthCallback);
            
            }
            Response.Write("Your application is now authorized.");
        }

        public void error(HttpStatusCode code, string descr)
        {
            Response.StatusCode = (int)code;
            Response.StatusDescription = descr;
        }
    }
}